import {Util} from "../util/Util";

export class LngLat {
  lng: number;
  lat: number;

  constructor(lng: number, lat: number) {
    if (isNaN(lng) || isNaN(lat)) {
      throw new Error(`Invalid LngLat object: (${lng}, ${lat})`);
    }
    this.lng = +lng;
    this.lat = +lat;
    if (this.lat > 90 || this.lat < -90) {
      throw new Error("Invalid LngLat latitude value: must be between -90 and 90");
    }
  }

  /**
   * Returns a new `LngLat` object whose longitude is wrapped to the range (-180, 180).
   *
   * @returns {LngLat} The wrapped `LngLat` object.
   * @example
   * var ll = new mapboxgl.LngLat(286.0251, 40.7736);
   * var wrapped = ll.wrap();
   * wrapped.lng; // = -73.9749
   */
  wrap() {
    return new LngLat(Util.wrap(this.lng, -180, 180), this.lat);
  }

  /**
   * Returns the coordinates represented as an array of two numbers.
   *
   * @returns {Array<number>} The coordinates represeted as an array of longitude and latitude.
   * @example
   * var ll = new mapboxgl.LngLat(-73.9749, 40.7736);
   * ll.toArray(); // = [-73.9749, 40.7736]
   */
  toArray() {
    return [this.lng, this.lat];
  }

  /**
   * Returns the coordinates represent as a string.
   *
   * @returns {string} The coordinates represented as a string of the format `"LngLat(lng, lat)"`.
   * @example
   * var ll = new mapboxgl.LngLat(-73.9749, 40.7736);
   * ll.toString(); // = "LngLat(-73.9749, 40.7736)"
   */
  toString() {
    return `LngLat(${this.lng}, ${this.lat})`;
  }
}